import { delay } from './'

export default class Signal {
  constructor(options) {
    this.serial = ['Red', 'Yellow', 'Green']
    this.sig = options.init
    this.times = options.times || [10, 3, 5]
    this.eventMap = new Map()
    this.eventMap.set('tick', new Set())
    this.eventMap.set('change', new Set())
    this.setTime()
    this.exchange()
  }

  get next() {
    const index = (this.serial.indexOf(this.sig) + 1) % this.serial.length

    return this.serial[index]
  }

  get remain() {
    const diff = this.endTime - Date.now()
    if (diff <= 0) {
      return 0
    }

    return diff / 1000
  }

  setTime() {
    this.startTime = Date.now()
    const time = this.times[this.serial.indexOf(this.sig)]
    this.endTime = this.startTime + time * 1000
  }

  async exchange() {
    await 1
    if (this.remain > 0) {
      // 不需要切换
      await delay(1000)
      this.emit('tick')
    } else {
      // 需要切换
      this.sig = this.next
      this.setTime()
      this.emit('change')
    }

    this.exchange()
  }

  on(event, handler) {
    this.eventMap.get(event).add(handler)
  }

  off(event, handler) {
    this.eventMap.get(event).delete(handler)
  }

  emit(event) {
    this.eventMap.get(event).forEach(e => {
      e.call(this, this)
    })
  }
}
